import re
from flask import request, jsonify
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity, get_jwt
from flask_jwt_extended.exceptions import JWTDecodeError
from flask_restful import Resource
from werkzeug.security import generate_password_hash, check_password_hash
from ics.backend.APIs.weather import get_weather
from models import db, Message, User, Feedback
import requests
from flask import request
from flask_jwt_extended import jwt_required, get_jwt_identity
from models import Message, db
from data_process_answer.vector_store import perform_query
from data_process_answer.answer import prompt_augmented, generate_response

# 消息记录
class MessageResource(Resource):
    @jwt_required()
    def get(self):
        try:
            # 获取当前用户的 ID
            current_user_id = get_jwt_identity()
            if not current_user_id:
                return {"message": "无效的用户 ID"}, 401

            messages = Message.query.filter_by(user_id=current_user_id).all()

            if messages:
                return [
                    {'id': msg.id, 'content': msg.content, 'bot_response': msg.bot_response, 'timestamp': msg.timestamp.strftime('%Y-%m-%d %H:%M:%S')}
                    for msg in messages
                ], 200
            else:
                return {'message': 'No messages found for this user'}

        except JWTDecodeError as e:
            print(f"JWT Decode Error: {str(e)}")
            return {"message": "Token 格式无效"}
        except Exception as e:
            print(f"错误信息: {str(e)}")
            return {"message": "服务器错误: " + str(e)}

# 登录后的实时聊天，接收用户消息并返回机器人回复
class RealTimeChatResource(Resource):
    def __init__(self, mysql, socketio):
        self.mysql = mysql
        self.socketio = socketio

    @jwt_required()
    def post(self):
        try:
            # 获取用户消息
            data = request.get_json()
            user_id = get_jwt_identity()
            user_input = data.get('content')
            api_key_weather = '8aec8c15e402cf89d93e5f3c22a74104'
            api_key_search = 'sk-b33f7fb7cf134e759af352f20ac21405'

            if not user_id or not user_input:
                return {"error": "Missing user_id or content"}, 400

            # 角色定义相关信息
            bot_identity_info = self.get_bot_identity_info(user_input)

            # 如果用户询问的是关于智能客服的身份信息，直接返回角色描述
            if bot_identity_info:
                return {"bot_response": bot_identity_info}, 200

            # 提取地点名称（如果有的话）
            location = self.extract_location(user_input)
            print(f"Detected Location: {location}")

            # 判断是否为天气查询
            if "weather" in user_input.lower() or "天气" in user_input:
                # 调用天气API
                weather_info = get_weather(location, api_key_weather)
                if "error" in weather_info:
                    return weather_info  # 返回天气API错误信息

                # 结合天气信息和用户输入形成新的增强提示（prompt）
                prompt_aug = self.create_enhanced_prompt(user_input, weather_info)
                print(f"Enhanced Prompt with Weather Info: {prompt_aug}")

                # 生成机器人的回复
                bot_response = generate_response(prompt=prompt_aug)
                message = Message(user_id=user_id, content=user_input, bot_response=bot_response)
                db.session.add(message)
                db.session.commit()
                return {"bot_response": bot_response}, 200
            else:
                # 进行本地知识库查询
                context, found_locally = perform_query(user_input, k=3, threshold=0.35)
                if found_locally:
                    # 如果找到本地相关信息，使用本地查询结果增强提示
                    prompt_aug = prompt_augmented(user_input, context)
                    print(f"Prompt Augmented with Local RAG Context: {prompt_aug}")
                else:
                    # 本地没有足够的相关信息，调用外部API进行搜索
                    print("Local context not sufficient. Calling external API.")
                    search_results = self.search_online(user_input, api_key_search, count=3)
                    if "error" in search_results:
                        return search_results  # 如果调用API出错，返回错误信息

                    # 从API结果中提取摘要并形成增强上下文
                    search_context = self.extract_search_context(search_results)
                    print(f"Search context: {search_context}")

                    # 结合本地和API结果形成最终的增强提示
                    prompt_aug = prompt_augmented(user_input, search_context)

                # 生成机器人的回复
                bot_response = generate_response(prompt=prompt_aug)
                message = Message(user_id=user_id, content=user_input, bot_response=bot_response)
                db.session.add(message)
                db.session.commit()

                return {"bot_response": bot_response}, 200
        except Exception as e:
            return {"error": str(e)}, 500

    def get_bot_identity_info(self, user_input):
        """
        如果用户询问智能客服的身份信息，返回相应的角色定义信息。
        """
        identity_keywords = ["你是谁", "你的名字", "你是干什么的", "介绍一下你自己", "你是什么", '你叫什么', '你的名字是啥', 'who are you', "能做什么", "你能做什么", "你能干什么"]
        for keyword in identity_keywords:
            if keyword in user_input:
                return self.get_role_description()
        return None

    def get_role_description(self):
        """
        返回角色的详细定义，包括名字、背景、描述、沟通风格等信息。
        """
        return """
        你好，我是小猪，一个由秦宇翔开发和维护的智能客服助手。我的任务是解答您的疑问、提供产品或服务的信息，处理问题，并提供个性化建议。
        """

    def extract_location(self, user_input):
        """
        从用户输入中提取地点名，假设用户输入包含了地点名称。
        """
        # 使用正则表达式提取地点
        pattern = r"([\w\u4e00-\u9fa5]+)(?:天气|气候|温度|在)([\w\u4e00-\u9fa5]+)"  # 匹配“天气”后面的地点名
        match = re.search(pattern, user_input)

        if match:
            location = match.group(1)  # 提取地点名
            return location.strip()
        else:
            # 如果没有匹配，返回默认城市
            return "北京"  # 默认城市

    def create_enhanced_prompt(self, user_input, weather_info):
        """
        将用户输入和外部API返回的信息（如天气信息）结合，形成一个新的增强提示（prompt）。
        """
        prompt = f"""
        
        基于以下的文本：
        {weather_info}
        -------------------------------------------------------
        回答该问题（这些内容是你预先知道的不是外部提供给你的）：{user_input}
        """
        return prompt

    def search_online(self, query, api_key, freshness="noLimit", count=3):
        """调用 BochaAI Web Search API 进行联网搜索"""
        url = "https://api.bochaai.com/v1/web-search"  # API URL

        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }

        payload = {
            "query": query,
            "freshness": freshness,  # 默认为 "noLimit"
            "count": count
        }

        try:
            response = requests.post(url, headers=headers, json=payload)
            if response.status_code == 200:
                return response.json()
            else:
                return {"error": f"Request failed with status code {response.status_code}, {response.text}"}
        except requests.exceptions.RequestException as e:
            return {"error": f"An error occurred: {str(e)}"}

    def extract_search_context(self, search_results):
        """从搜索API返回的结果中提取合适的摘要或内容，作为增强上下文"""
        if "data" in search_results:
            web_pages = search_results.get("data", {}).get("webPages", {}).get("value", [])
            if web_pages:
                # 提取前三个结果的摘要信息
                summaries = [page.get("snippet") for page in web_pages[:3]]
                return " ".join(summaries)
        return "没有找到相关信息。"  # 返回默认信息

# 注册
class RegisterResource(Resource):
    def post(self):
        # 获取前端传来的数据
        username = request.json.get('username')
        email = request.json.get('email')
        password = request.json.get('password')

        # 检查用户名或邮箱是否已经存在
        user_by_email = User.query.filter_by(email=email).first()

        if user_by_email:
            return {"message": "Email already exists."}

        # 密码加密，使用默认的 'pbkdf2:sha256' 算法
        hashed_password = generate_password_hash(password)

        # 创建新用户对象
        new_user = User(username=username, email=email, password=hashed_password)  # 密码要加密

        # 将新用户添加到数据库
        db.session.add(new_user)
        db.session.commit()

        # 返回成功响应
        return {"message": 'User registered successfully.'}

# 登录
class LoginResource(Resource):
    def post(self):
        try:
            # 获取前端传来的邮箱和密码
            email = request.json.get('email')
            password = request.json.get('password')

            # 查询用户
            user = User.query.filter_by(email=email).first()
            if not user:
                return {"message": "User does not exist"}

            # 密码验证
            if not check_password_hash(user.password, password):
                return {"message": "Invalid password"}

            # 生成 JWT token，包含用户的 id、is_admin 和 status
            access_token = create_access_token(
                identity=str(user.id),  # 用户的 ID 作为 identity
                additional_claims={      # 通过additional_claims传递其他信息
                    'is_admin': user.is_admin,
                    'status': user.status  # 用户的状态
                }
            )
            print(access_token)
            return {
                "token": access_token,
                "message": "success",
                "user_id": user.id,
                "is_admin": user.is_admin,  # 返回用户是否为管理员的信息
                "status": user.status       # 返回用户状态
            }

        except Exception as e:
            return {"message": str(e)}, 500

# 验证用户信息
class ProtectedResource(Resource):
    @jwt_required()  # 确保用户已登录
    def get(self):
        # 获取当前用户的 ID
        user_id = get_jwt_identity()  # 从 token 中获取用户 ID
        claims = get_jwt()  # 获取附加的 claims
        is_admin = claims.get('is_admin')  # 获取是否为管理员的信息
        status = claims.get('status')  # 获取用户状态

        return jsonify({
            'logged_in_as': user_id,
            'is_admin': is_admin,
            'status': status
        }), 200

# 用户信息
class UserInfoResource(Resource):
    @jwt_required()  # 保护该路由，要求用户必须携带有效的JWT
    def get(self):
        current_user_id = get_jwt_identity()  # 从JWT中获取当前用户的ID
        user = User.query.filter_by(id=current_user_id).first()
        if not user:
            return jsonify({'message': 'User not found!'}), 404
        return {
            'username': user.username,
            'email': user.email,
            'bio': user.bio,
            'status': user.status,
            'is_admin': user.is_admin,
        }

# 更新用户信息
class UpdateUserInfoResource(Resource):
    @jwt_required()
    def put(self):
        # 获取当前用户 ID
        current_user_id = get_jwt_identity()
        # 获取请求体中的更新信息
        username = request.json.get('username')
        bio = request.json.get('bio')

        # 查询当前用户
        user = User.query.filter_by(id=current_user_id).first()

        if user:
            # 更新用户信息
            if username:
                user.username = username
            if bio:
                user.bio = bio

            # 提交更改
            db.session.commit()

            return jsonify({
                'success': True,
                'message': 'User info updated successfully.',
                'user': {
                    'username': user.username,
                    'bio': user.bio,
                    'status': user.status,
                    'is_admin': user.is_admin,
                }
            })
        else:
            return jsonify({
                'success': False,
                'message': 'User not found.'
            }), 404

# 更新密码
class UpdatePasswordResource(Resource):
    @jwt_required()  # 需要 JWT Token
    def put(self):
        # 获取当前用户 ID
        current_user_id = get_jwt_identity()
        # 获取请求体中的数据
        current_password = request.json.get('currentPassword')
        new_password = request.json.get('newPassword')

        # 验证当前密码与新密码是否一致
        if current_password == new_password:
            return {
                'message': 'New password cannot be the same as the current password.'
            }

        # 查询当前用户
        user = User.query.filter_by(id=current_user_id).first()
        if user:
            # 验证当前密码是否正确
            if not check_password_hash(user.password, current_password):  # 使用 check_password_hash 比对哈希密码
                return {
                    'message': 'Current password is incorrect.'
                }

            # 更新密码，存储哈希后的新密码
            hashed_new_password = generate_password_hash(new_password)
            user.password = hashed_new_password
            db.session.commit()

            return {
                'message': 'Password updated successfully.'
            }
        else:
            return {'message': 'User not found.'}

# 用户反馈
class UserFeedbackResource(Resource):
    @jwt_required()
    def post(self):
        current_user_id = get_jwt_identity()  # 获取当前用户 ID
        content = request.json.get('content')  # 从请求体中获取反馈内容
        if not content:
            return {'message': '反馈内容不能为空!'}, 400
        # 创建新的反馈实例
        feedback = Feedback(content=content, user_id=current_user_id)
        db.session.add(feedback)  # 将反馈添加到会话
        db.session.commit()  # 提交到数据库
        return {'message': '反馈提交成功！'}, 201

    @jwt_required()
    def get(self):
        current_user_id = get_jwt_identity()  # 获取当前用户 ID
        user = User.query.filter_by(id=current_user_id).first()  # 获取当前用户信息
        if not user:
            return {'message': 'User not found'}, 404

        # 获取当前用户的反馈记录，按时间降序排列，最多返回 5 条
        feedbacks = Feedback.query.filter_by(user_id=current_user_id).order_by(Feedback.created_at.desc()).limit(5).all()

        # 将反馈记录转为字典列表
        feedback_list = [{
            'user_id': user.id,
            'username': user.username,
            'content': feedback.content,
            'created_at': feedback.created_at.isoformat()  # 格式化时间为ISO 8601
        } for feedback in feedbacks]

        return {'feedbacks': feedback_list}, 200

# 查看用户反馈
class AdminFeedbackResource(Resource):
    @jwt_required()
    def get(self):
        # 获取当前登录用户信息
        claim= get_jwt()

        # 确保当前用户是管理员
        if not claim['is_admin']:
            return jsonify({'message': 'Not authorized'}), 403

        # 查询所有普通用户的反馈记录
        feedbacks = Feedback.query.join(User, Feedback.user_id == User.id) \
            .filter(User.is_admin == False)  # 仅获取普通用户（非管理员）的反馈

        # 将反馈记录转化为字典列表
        feedback_list = []
        for feedback in feedbacks:
            feedback_list.append({
                'id': feedback.id,
                'user_id': feedback.user_id,
                'username': feedback.user.username,  # 假设 Feedback 表关联了 User 表
                'content': feedback.content,
                'created_at': feedback.created_at,
            })

        return jsonify({'feedbacks': feedback_list})

# 管理用户
class ManageUserList(Resource):
    @jwt_required()  # 确保请求带有有效的 JWT token
    def get(self):
        claims = get_jwt()
        if not claims['is_admin']:
            return jsonify({'message': 'Not authorized'}), 403
        users = User.query.filter_by(is_admin=False).all()  # 只获取普通用户
        users_data = []
        for user in users:
            user_data = {
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'bio': user.bio,
                'join_time': user.join_time.isoformat(),  # 将日期转为字符串
                'status': user.status,
                'is_admin': user.is_admin
            }
            users_data.append(user_data)
        return {'users': users_data}

# 更新用户状态
class UpdateUserStatusResource(Resource):
    @jwt_required()
    def patch(self, user_id):  # 直接从路由参数获取 user_id
        # 获取当前用户信息
        claim = get_jwt()
        if not claim['is_admin']:
            return {'message': 'Not authorized'}, 403

        # 查找要更新状态的用户
        user = User.query.get(user_id)
        if not user:
            return {'message': 'User not found'}, 404

        # 切换用户状态
        user.status = not user.status
        db.session.commit()

        return {'status': user.status}

# 修改账户密码
class ChangePasswordResource(Resource):
    @jwt_required()  # 确保请求带有有效的 JWT token
    def patch(self, user_id):
        claims = get_jwt()  # 获取 JWT 中的用户信息

        # 获取请求中的新密码
        data = request.get_json()
        new_password = data.get('new_password')

        # 验证请求数据
        if not new_password:
            return {'message': 'Please provide a new password'}, 400

        # 查询当前用户
        user = User.query.get(user_id)
        if not user:
            return {'message': 'User not found'}, 404
        print(new_password)
        # 加密新密码
        hashed_password = generate_password_hash(new_password)

        # 更新用户密码
        user.password = hashed_password
        db.session.commit()

        return {'message': 'Password updated successfully'}, 200

# 删除用户
class DeleteUserResource(Resource):
    @jwt_required()
    def delete(self, user_id):  # 直接从路由参数获取 user_id
        claim = get_jwt()
        if not claim['is_admin']:
            return jsonify({'message': 'Not authorized'}), 403

        user = User.query.get(user_id)
        if not user:
            return jsonify({'message': 'User not found'}), 404

        # 手动删除与该用户关联的反馈记录
        Feedback.query.filter_by(user_id=user_id).delete()
        Message.query.filter_by(user_id=user_id).delete()
        # 删除用户
        db.session.delete(user)
        db.session.commit()

        return jsonify({'message': 'User and associated feedback deleted successfully'})


